import { Canvas, Meta, Controls } from '@storybook/addon-docs/blocks';

import * as LoaderStories from './Loader.stories';
import * as OverlayLoaderStories from './OverlayLoader.stories';

<Meta title="Components/Loader" />

# Loader

The Loader components provide visual feedback to users when content is loading or an operation is in progress.
Webiny offers two loader components:

1. -  **Loader** - A standalone circular progress indicator.
2. -  **OverlayLoader** - The OverlayLoader covers its parent container with a semi-transparent overlay, typically used to indicate a loading state while keeping the background content visible but inactive. Please refer below for more examples.

## Loader

The Loader component displays a circular progress indicator that can be used to show loading states or progress of operations.

<Canvas of={LoaderStories.Documentation} source={ { code: `
import React from "react";
import { Loader } from "@webiny/admin-ui";

const LoaderExample = () => {
    return (
        <div className="flex flex-col items-center gap-4">
            <Loader
                size="md"
                variant="accent"
                indeterminate={true}
                text="Loading..."
            />
        </div>
    );
};

export default LoaderExample;

` } }
    additionalActions={[
        {
            title: 'Open in GitHub',
            onClick: () => {
                window.open(
                    'https://github.com/webiny/webiny-js/blob/feat/new-admin-ui/packages/admin-ui/src/Loader/Loader.tsx',
                    '_blank'
                );
            },
        }
    ]}
/>

<Controls of={LoaderStories.Documentation} />

```tsx
import React from "react";
import { Loader } from "@webiny/admin-ui";

const LoaderExample = () => {
    return (
        <div className="flex flex-col items-center gap-4">
            <Loader
                size="md"
                variant="accent"
                indeterminate={true}
                text="Loading..."
            />
        </div>
    );
};

export default LoaderExample;
```

### Loader Sizes

The Loader component supports four different sizes: xs, sm, md, and lg.

<Canvas of={LoaderStories.ExtraSmall} source={ { code: `
import React from "react";
import { Loader } from "@webiny/admin-ui";

const ExtraSmallLoaderExample = () => (
    <Loader size="xs" />
);

export default ExtraSmallLoaderExample;
` } } />

<Canvas of={LoaderStories.Small} source={ { code: `
import React from "react";
import { Loader } from "@webiny/admin-ui";

const SmallLoaderExample = () => (
    <Loader size="sm" />
);

export default SmallLoaderExample;
` } } />

<Canvas of={LoaderStories.Medium} source={ { code: `
import React from "react";
import { Loader } from "@webiny/admin-ui";

const MediumLoaderExample = () => (
    <Loader size="md" />
);

export default MediumLoaderExample;
` } } />

<Canvas of={LoaderStories.Large} source={ { code: `
import React from "react";
import { Loader } from "@webiny/admin-ui";

const LargeLoaderExample = () => (
    <Loader size="lg" />
);

export default LargeLoaderExample;
` } } />

### Loader Variants

The Loader component supports three different visual variants: accent, subtle, and negative.

<Canvas of={LoaderStories.Accent} source={ { code: `
import React from "react";
import { Loader } from "@webiny/admin-ui";

const AccentLoaderExample = () => (
    <Loader variant="accent" />
);

export default AccentLoaderExample;
` } } />

<Canvas of={LoaderStories.Subtle} source={ { code: `
import React from "react";
import { Loader } from "@webiny/admin-ui";

const SubtleLoaderExample = () => (
    <Loader variant="subtle" />
);

export default SubtleLoaderExample;
` } } />

<Canvas of={LoaderStories.Negative} source={ { code: `
import React from "react";
import { Loader } from "@webiny/admin-ui";

const NegativeLoaderExample = () => (
    <div className="bg-primary p-md rounded-md">
        <Loader variant="negative" />
    </div>
);

export default NegativeLoaderExample;
` } } />

### Controlled Progress

You can use the Loader component to display determinate progress by setting the `indeterminate` prop to `false` and providing a `value`.

<Canvas of={LoaderStories.WithControlledValue} source={ { code: `
import React, { useState, useEffect } from "react";
import { Loader } from "@webiny/admin-ui";

const ControlledProgressExample = () => {
    const [value, setValue] = useState(0);

    useEffect(() => {
        const interval = setInterval(() => {
            setValue((prevValue = 0) => {
                if (prevValue === 100) {
                    return prevValue;
                }
                return prevValue + 5;
            });
        }, 50);

        return () => clearInterval(interval);
    }, []);

    return (
        <Loader
            value={value}
            indeterminate={false}
            text={"Loading " + value + "%"}
        />
    );
};

export default ControlledProgressExample;
` } } />

### Loader with Text

You can add descriptive text below the loader using the `text` prop.

<Canvas of={LoaderStories.WithText} source={ { code: `
import React from "react";
import { Loader } from "@webiny/admin-ui";

const LoaderWithTextExample = () => (
    <Loader text="Loading..." />
);

export default LoaderWithTextExample;
` } } />

## OverlayLoader

The OverlayLoader component displays a loader on top of its parent container with a semi-transparent overlay. It's useful for indicating loading states for specific sections of your UI.

<Canvas of={OverlayLoaderStories.Documentation} source={ { code: `
import React from "react";
import { OverlayLoader } from "@webiny/admin-ui";

const OverlayLoaderExample = () => {
    return (
        <div className="relative h-64 w-full bg-neutral-light rounded-md p-4">
            <OverlayLoader
                size="lg"
                variant="accent"
                text="Loading content..."
            />
            <div className="h-full flex items-center justify-center">
                <p className="text-neutral-strong">Content is loading...</p>
            </div>
        </div>
    );
};

export default OverlayLoaderExample;

` } }
    additionalActions={[
        {
            title: 'Open in GitHub',
            onClick: () => {
                window.open(
                    'https://github.com/webiny/webiny-js/blob/feat/new-admin-ui/packages/admin-ui/src/Loader/OverlayLoader.tsx',
                    '_blank'
                );
            },
        }
    ]}
/>

<Controls of={OverlayLoaderStories.Documentation} />

```tsx
import React from "react";
import { OverlayLoader } from "@webiny/admin-ui";

const DefaultOverlayLoaderExample = () => (
    <div>
        <OverlayLoader />
        The OverlayLoader component covers its parent container with a semi-transparent overlay, typically used to indicate a loading state while keeping the background content visible but inactive.
    </div>
);

export default DefaultOverlayLoaderExample;
```

### Default OverlayLoader

<Canvas of={OverlayLoaderStories.Default} source={ { code: `
import React from "react";
import { OverlayLoader } from "@webiny/admin-ui";

const DefaultOverlayLoaderExample = () => (
    <div>
        <OverlayLoader />
        The OverlayLoader component covers its parent container with a semi-transparent overlay, typically used to indicate a loading state while keeping the background content visible but inactive.
    </div>
);

export default DefaultOverlayLoaderExample;
` } } />

### OverlayLoader with Text

<Canvas of={OverlayLoaderStories.CircularProgressWithText} source={ { code: `
import React from "react";
import { OverlayLoader } from "@webiny/admin-ui";

const OverlayLoaderWithTextExample = () => (
    <div>
        <OverlayLoader text="Loading..." />
         The OverlayLoader component covers its parent container with a semi-transparent overlay, typically used to indicate a loading state while keeping the background content visible but inactive.
    </div>
);

export default OverlayLoaderWithTextExample;
` } } />

## Anatomy

### Construction
<img src="/images/storybook/loader/construction.png" alt="Construction"/>

### Style
<img src="/images/storybook/loader/style.png" alt="Style"/>

### Type

A **determinate** circular loader visually represents progress with a circular arc that fills proportionally based on the completed percentage, providing users with a clear indication of task completion.

An **indeterminate loader** does not display exact progress but continuously animates, signaling that a process is ongoing without a known completion time.

<img src="/images/storybook/loader/type.png" alt="Type"/>

### Size
<img src="/images/storybook/loader/size.png" alt="Size"/>

### Background Overlay
<img src="/images/storybook/loader/background-overlay.png" alt="Background Overlay"/>

## Usage

<img src="/images/storybook/loader/usage-1.png" alt="Usage"/>

<img src="/images/storybook/loader/usage-2.png" alt="Usage"/>
